package com.zg.invoice.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.smallbun.screw.core.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zg.common.core.dao.BaseEntity;
import com.zg.common.core.exception.BusinessException;
import com.zg.invoice.dao.*;
import com.zg.invoice.dao.mapper.JsInvoiceConfMapper;
import com.zg.invoice.dao.mapper.JsInvoiceOpenDetailMapper;
import com.zg.invoice.dao.mapper.JsInvoiceOpenMapper;
import com.zg.invoice.dao.mapper.JsInvoiceOpenTaskMapper;
import com.zg.invoice.enm.InvoiceSystemEnum;
import com.zg.invoice.service.InvoiceService;
import com.zg.invoice.util.LeqiApiUtil;
import com.zg.invoice.util.NuoNuoApiUtil;
import com.zg.invoice.vo.*;
import com.zg.invoice.vo.leqi.LeqiInvoiceRedReq;
import com.zg.invoice.vo.leqi.LeqiInvoiceRedRes;
import com.zg.invoice.vo.nuonuo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class InvoiceServiceImpl implements InvoiceService {

    @Resource
    private LeqiApiUtil leqiApiUtil;
    @Resource
    private NuoNuoApiUtil nuoNuoApiUtil;
    @Resource
    private JsInvoiceOpenTaskMapper jsInvoiceOpenTaskMapper;
    @Resource
    private JsInvoiceOpenMapper jsInvoiceOpenMapper;
    @Resource
    private JsInvoiceOpenDetailMapper jsInvoiceOpenDetailMapper;
    @Resource
    private JsInvoiceOpenTaskDao jsInvoiceOpenTaskDao;
    @Value("${invoice.callBack.url}")
    private  String callBackUrl ;
    @Resource
    private JsInvoiceConfMapper jsInvoiceConfMapper;

   public static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 开蓝票
     * @param openInvoiceReq
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String invoice(OpenInvoiceReq openInvoiceReq) {
        String invoiceSystem = openInvoiceReq.getInvoiceSystem();
        if (InvoiceSystemEnum.checkHave(invoiceSystem)){
            String callBackUrl=openInvoiceReq.getBizCallbackUrl();
            openInvoiceReq.setBizCallbackUrl(callBackUrl);
//            if (InvoiceSystemEnum.LE_QI.getCode().equals(invoiceSystem)){
//                LeqiOpenInvoiceRes leqiOpenInvoiceRes = leqiApiUtil.sendOpenInvoice(openInvoiceReq);
//                if (!(leqiOpenInvoiceRes.getCode()==0000)) {
//                    return "乐企系统提示：【" + leqiOpenInvoiceRes.getMsg() +"】。如有疑问请咨询结算运维人员。";
//                }
//            }else if (InvoiceSystemEnum.NUO_NUO.getCode().equals(invoiceSystem)){
//                OpenInvoiceRes openInvoiceRes = nuoNuoApiUtil.sendOpenInvoice(openInvoiceReq);
//                if ( !(openInvoiceRes.getCode()==200)) {
//                    return "诺税通系统提示：【" + openInvoiceRes.getMessage() +"】。如有疑问请咨询结算运维人员。";
//                }
//            }
            JsInvoiceOpenTask jsInvoiceOpenTask = new JsInvoiceOpenTask();
            String purchaser_address = openInvoiceReq.getBuyerAddress()+" "+openInvoiceReq.getBuyerPhone();
            String purchaser_bank_name = openInvoiceReq.getBuyerBank()+" "+openInvoiceReq.getBuyerAccount();
            jsInvoiceOpenTask.setInvoiceType(null)//任务不需要该类型置空
                    .setExternalDocumentNo(openInvoiceReq.getOrderNo())//订单号唯一UUID
                    .setStatus(0L)//设置开票任务为开票中
                    .setInvoiceStatus(40L)//发票状态:40:等待处理结果
                    .setDrawer(openInvoiceReq.getClerker())//开票人
                    .setReviewer(openInvoiceReq.getChecker())
                    .setPayee(openInvoiceReq.getPayee())//收款人
                    .setPurchaserName(openInvoiceReq.getBuyerName())//购方名称
                    .setPurchaserTaxNo(openInvoiceReq.getBuyerTaxnum())//购方税号
                    .setPurchaserAddress(purchaser_address)
                    .setPurchaserBankName(purchaser_bank_name)
                    .setSourceSystem(openInvoiceReq.getSourceSystem())
                    .setSourceCallbackUrl(callBackUrl)
                    .setBillingType(0L)
                    .setInvoiceSystem(invoiceSystem);
            jsInvoiceOpenTaskMapper.insert(jsInvoiceOpenTask);
            return "";
        }else {
            return "没有相关的开票系统检查数据！！!";
        }
    }

    /**
     * 发票回调
     * @param callBack
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean callBack(InvoiceCallBack callBack) {
        log.info("发票回调调接口数据为：{}" , JSONUtil.toJsonStr(callBack));
        JsInvoiceOpen jsInvoiceOpen = JsInvoiceOpen.toJsInvoiceOpen(callBack);
        boolean success = true;
        //开票成功
        if (1 == callBack.getInvoiceStatus()){
            //蓝票
            if (1 == callBack.getInvoiceType()){
                //税局发票处理
                String externalDocumentNo = jsInvoiceOpen.getExternalDocumentNo();
                if (externalDocumentNo.length() != 32) {
                    if (!"bs".equals(callBack.getInvoiceLine())) {
                        BusinessException.happen("非数电专票，回传失败");
                    }
                    if (StringUtils.isEmpty(callBack.getPdfUrl()) || StringUtils.isEmpty(callBack.getXmlUrl()) || StringUtils.isEmpty(callBack.getOfdUrl())) {
                        BusinessException.happen("文件地址为空，回传失败");
                    }
                    List<OpenInvoiceDetails> detail = callBack.getDetail();
                    if (detail == null || detail.isEmpty()) {
                        BusinessException.happen("发票明细为空，回传失败");
                    }
                }
                LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapperT = new LambdaQueryWrapper<>();
                queryWrapperT.eq(JsInvoiceOpenTask::getExternalDocumentNo, externalDocumentNo).in(JsInvoiceOpenTask::getStatus, Arrays.asList("0","2"))//查询开票中和开票失败
                ;
                List<JsInvoiceOpenTask> jsInvoiceOpenTaskList = jsInvoiceOpenTaskMapper.selectList(queryWrapperT);
                //开具成功（根据发票任务表中的订单号获取orgId插入到发票表中）
                if (ObjectUtils.isNotEmpty(jsInvoiceOpenTaskList)) {
                    log.info("查询任务表中数据：{}"+jsInvoiceOpenTaskList.toString());
                    JsInvoiceOpenTask jsInvoiceOpenTask = new JsInvoiceOpenTask();
                    BeanUtils.copyProperties(jsInvoiceOpen, jsInvoiceOpenTask);
                    //更新任务状态(及数据)
                    jsInvoiceOpenTaskMapper.update(jsInvoiceOpenTask.setStatus(1L), queryWrapperT);
                    addInvoiceOpen(jsInvoiceOpen);
                    List<JsInvoiceOpenDetail> detailList = jsInvoiceOpen.getDetailList();
                    for (JsInvoiceOpenDetail jsInvoiceOpenDetail : detailList) {
                        //添加发票详情（该详情只能从回调接口获取，无法主动查询）
                        jsInvoiceOpenDetail.setExternalDocumentNo(jsInvoiceOpen.getExternalDocumentNo());
                        addInvoiceOpenDetail(jsInvoiceOpenDetail);
                    }
                }else {
                    log.info("开票任务表没有查询到开票进行中的数据，订单编号：{}"+jsInvoiceOpen.getExternalDocumentNo());
                    //由于诺税通回调的xmlUrl地址不是实时产生的，所以如果没有查询到开票进行中的数据，说明可能已经开票完成，开票完成的更新发票信息及推送长协信息
                    LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(JsInvoiceOpenTask::getExternalDocumentNo, jsInvoiceOpen.getExternalDocumentNo())
                            .eq(JsInvoiceOpenTask::getStatus, 1);//查询开票完成
                    List<JsInvoiceOpenTask> jsInvoiceOpenTasks = jsInvoiceOpenTaskMapper.selectList(queryWrapper);
                    if (ObjectUtils.isNotEmpty(jsInvoiceOpenTasks)) {
                        log.info("开票任务表查询到开票完成的数据，订单编号：{}"+jsInvoiceOpen.getExternalDocumentNo());
                        updateInvoiceOpen(jsInvoiceOpen);
                    }else {
                        BusinessException.happen("开票任务表没有查询到开票完成的数据，订单编号：{}"+jsInvoiceOpen.getExternalDocumentNo());
                    }
                }
            }
            //红票
            else if (2 == callBack.getInvoiceType()){
                LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapper2 = new LambdaQueryWrapper<>();
                queryWrapper2.eq(JsInvoiceOpenTask::getParentInvoiceNo, callBack.getOriInvoiceNumber());
                List<JsInvoiceOpenTask> jsInvoiceOpenTasks = jsInvoiceOpenTaskMapper.selectList(queryWrapper2);
                if (CollectionUtils.isEmpty(jsInvoiceOpenTasks)) return true;
                jsInvoiceOpenTasks.forEach(line->{
                    JsInvoiceOpenTask jsInvoiceOpenTask = new JsInvoiceOpenTask();
                    BeanUtils.copyProperties(jsInvoiceOpen,jsInvoiceOpenTask);
                    jsInvoiceOpenTask.setId(line.getId());
                    jsInvoiceOpenTask.setInvoiceStatus(10L);
                    jsInvoiceOpenTask.setExternalDocumentNo(line.getExternalDocumentNo());
                    log.info("JsInvoiceOpenRecord修改红票信息为：{}", JSONUtil.toJsonStr(jsInvoiceOpenTask));
                    jsInvoiceOpenTaskMapper.updateById(jsInvoiceOpenTask);
                });

                //修改1
                LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(JsInvoiceOpenTask::getInvoiceNo, callBack.getOriInvoiceNumber());
                jsInvoiceOpenTaskMapper.update(new JsInvoiceOpenTask().setInvoiceStatus(20L), queryWrapper);
                //修改3
                LambdaQueryWrapper<JsInvoiceOpen> queryWrapper3 = new LambdaQueryWrapper<>();
                queryWrapper3.eq(JsInvoiceOpen::getInvoiceNo, jsInvoiceOpen.getOldInvoiceNo());
                jsInvoiceOpenMapper.update(new JsInvoiceOpen().setInvoiceStatus(20L), queryWrapper3);
                jsInvoiceOpen.setInvoiceStatus(10L);
                jsInvoiceOpen.setId(null);
                jsInvoiceOpen.setParentInvoiceNo(callBack.getOriInvoiceNumber());
                jsInvoiceOpen.setExternalDocumentNo(jsInvoiceOpen.getExternalDocumentNo());
                log.info("JsInvoiceOpen新增红票信息为：{}", JSONUtil.toJsonStr(jsInvoiceOpen));
                Map<String, Object> inMap = new HashMap<>();
                inMap.put("INVOICE_NO", jsInvoiceOpen.getInvoiceNo());
                jsInvoiceOpenMapper.deleteByMap(inMap);
                jsInvoiceOpenMapper.insert(jsInvoiceOpen);
                List<JsInvoiceOpenDetail> jsInvoiceOpenDetails = jsInvoiceOpenDetailMapper.selectList(new LambdaQueryWrapper<JsInvoiceOpenDetail>()
                        .eq(JsInvoiceOpenDetail::getExternalDocumentNo, jsInvoiceOpen.getExternalDocumentNo()));
                if (CollectionUtils.isEmpty(jsInvoiceOpenDetails)){
                    List<JsInvoiceOpenDetail> detailList = jsInvoiceOpen.getDetailList();
                    for (JsInvoiceOpenDetail jsInvoiceOpenDetail : detailList) {
                        //添加发票详情（该详情只能从回调接口获取，无法主动查询）
                        jsInvoiceOpenDetail.setExternalDocumentNo(jsInvoiceOpen.getExternalDocumentNo());
                        addInvoiceOpenDetail(jsInvoiceOpenDetail);
                    }
                }

            }
        }
        //开票失败
        else if (2 == callBack.getInvoiceStatus()){
            log.error(jsInvoiceOpen.getExternalDocumentNo()+"开票失败");
            log.info("发票回调失败数据：" + jsInvoiceOpen);
            LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapperT = new LambdaQueryWrapper<>();
            queryWrapperT.eq(JsInvoiceOpenTask::getExternalDocumentNo, jsInvoiceOpen.getExternalDocumentNo())
                    .eq(JsInvoiceOpenTask::getStatus, 0);//查询开票中
            List<JsInvoiceOpenTask> jsInvoiceOpenTaskList = jsInvoiceOpenTaskMapper.selectList(queryWrapperT);
            if (ObjectUtils.isNotEmpty(jsInvoiceOpenTaskList)) {
                JsInvoiceOpenTask jsInvoiceOpenTask = new JsInvoiceOpenTask();
                BeanUtils.copyProperties(jsInvoiceOpen, jsInvoiceOpenTask);
                //更新任务状态(及数据)
                jsInvoiceOpenTaskMapper.update(jsInvoiceOpenTask.setStatus(2L), queryWrapperT);
            }
            //红票的话将蓝票修改为正常
           if (2 == callBack.getInvoiceType()){
                log.info("红票回调失败数据：" + jsInvoiceOpen);
               LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapperR = new LambdaQueryWrapper<>();
               queryWrapperR.eq(JsInvoiceOpenTask::getExternalDocumentNo, jsInvoiceOpen.getExternalDocumentNo())
                       .eq(JsInvoiceOpenTask::getInvoiceNo, jsInvoiceOpen.getParentInvoiceNo());//查询开票中
               List<JsInvoiceOpenTask> jsInvoiceOpenTaskRList = jsInvoiceOpenTaskMapper.selectList(queryWrapperR);
               if (ObjectUtils.isNotEmpty(jsInvoiceOpenTaskRList)) {
                   JsInvoiceOpenTask jsInvoiceOpenTask = new JsInvoiceOpenTask();
                   BeanUtils.copyProperties(jsInvoiceOpen, jsInvoiceOpenTask);
                   //更新任务状态(及数据)
                   jsInvoiceOpenTaskMapper.update(jsInvoiceOpenTask.setInvoiceStatus(10L), queryWrapperT);
               }

            }
        }
        //发票作废成功
        else if (3 == callBack.getInvoiceStatus()){
            //判断是否已经处理过
            LambdaQueryWrapper<JsInvoiceOpen> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(JsInvoiceOpen::getInvoiceNo, jsInvoiceOpen.getInvoiceNo());
            JsInvoiceOpen invoiceOpen = jsInvoiceOpenMapper.selectOne(queryWrapper);
            if (invoiceOpen.getInvoiceStatus().compareTo(30L) == 0) {
                log.info("发票号码["+jsInvoiceOpen.getInvoiceNo()+"]作废回调已经处理过，无需重复处理");
                success= true;
            }
            //修改发票状态为作废
            invoiceOpen.setInvoiceStatus(30L);
            jsInvoiceOpenMapper.update(invoiceOpen, queryWrapper);
            LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapperT = new LambdaQueryWrapper<>();
            queryWrapperT.eq(JsInvoiceOpenTask::getInvoiceNo, jsInvoiceOpen.getInvoiceNo());
            JsInvoiceOpenTask invoiceOpenT = jsInvoiceOpenTaskMapper.selectOne(queryWrapperT);
            //修改发票状态为作废
            invoiceOpenT.setInvoiceStatus(30L);
            jsInvoiceOpenTaskMapper.update(invoiceOpenT, queryWrapperT);
        }
        //发票作废失败
        else if (4 == callBack.getInvoiceStatus()){

        }
        //开票失败删除成功
        else if (5 == callBack.getInvoiceStatus()){

        }
        //回调异常
        else {

        }
        return success;
    }

    @Override
    public IPage<JsInvoiceOpenTaskVo> invoicePageVo(InvoicePageReq invoicePageReq) {
        IPage<JsInvoiceOpenTask> pageParam = new Page<>(invoicePageReq.getPage(), invoicePageReq.getPageSize());
        QueryWrapper<JsInvoiceOpenTask> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(invoicePageReq.getSearchStr())) {
            queryWrapper.lambda().like(JsInvoiceOpenTask::getInvoiceNo, "%" + invoicePageReq.getSearchStr() + "%");
        }
        if (StrUtil.isNotBlank(invoicePageReq.getInvoiceNo())) {
            queryWrapper.lambda().like(JsInvoiceOpenTask::getInvoiceNo, "%" + invoicePageReq.getInvoiceNo() + "%");
        }
        if (StrUtil.isNotBlank(invoicePageReq.getSellerName())) {
            queryWrapper.lambda().like(JsInvoiceOpenTask::getSellerName, "%" + invoicePageReq.getSellerName() + "%");
        }
        if (StrUtil.isNotBlank(invoicePageReq.getPurchaserName())) {
            queryWrapper.lambda().like(JsInvoiceOpenTask::getPurchaserName, "%" + invoicePageReq.getPurchaserName() + "%");
        }
        if (StrUtil.isNotBlank(invoicePageReq.getPurchaserName())) {
            queryWrapper.lambda().like(JsInvoiceOpenTask::getPurchaserName, "%" + invoicePageReq.getPurchaserName() + "%");
        }
        if (StrUtil.isNotBlank(invoicePageReq.getSourceSystem())) {
            queryWrapper.lambda().eq(JsInvoiceOpenTask::getSourceSystem,  invoicePageReq.getSourceSystem() );
        }
        if (StrUtil.isNotBlank(invoicePageReq.getBillingType())) {
            queryWrapper.lambda().eq(JsInvoiceOpenTask::getBillingType,  invoicePageReq.getBillingType() );
        }
        if (ObjectUtils.isNotEmpty(invoicePageReq.getInvoiceType())) {
            queryWrapper.lambda().eq(JsInvoiceOpenTask::getInvoiceType,  invoicePageReq.getInvoiceType() );
        }
        if (ObjectUtils.isNotEmpty(invoicePageReq.getInvoiceStatus())) {
            queryWrapper.lambda().eq(JsInvoiceOpenTask::getInvoiceStatus,  invoicePageReq.getInvoiceStatus() );
        }
        queryWrapper.lambda().orderByDesc(JsInvoiceOpenTask::getCreateTime);
        if (StrUtil.isNotEmpty(invoicePageReq.getDrewDateEnd())) {
            try {
                Date date = formatter.parse(invoicePageReq.getDrewDateEnd());
                queryWrapper.lambda().le(JsInvoiceOpenTask::getDrewDate,  date );
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        if (StrUtil.isNotEmpty(invoicePageReq.getDrewDateBegin())) {
            try {
                Date date = formatter.parse(invoicePageReq.getDrewDateBegin());
                queryWrapper.lambda().ge(JsInvoiceOpenTask::getDrewDate,  date );
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        queryWrapper.lambda().orderByDesc(JsInvoiceOpenTask::getCreateTime);
        IPage<JsInvoiceOpenTask> result = jsInvoiceOpenTaskDao.page(pageParam, queryWrapper);
        IPage<JsInvoiceOpenTaskVo> voPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
        voPage.setRecords(result.getRecords().stream().map(task -> {
                    JsInvoiceOpenTaskVo vo = new JsInvoiceOpenTaskVo();
                    BeanUtils.copyProperties(task, vo);
                    return vo;
                }).collect(Collectors.toList()));
        return voPage;
    }

    @Override
    public String invoiceRed(OpenRedInvoiceReq openRedInvoiceReq) {
        String result= "";
        List<JsInvoiceOpenTask> jsInvoiceOpenTasks = jsInvoiceOpenTaskMapper.selectList(new LambdaQueryWrapper<JsInvoiceOpenTask>()
                .eq(JsInvoiceOpenTask::getInvoiceNo, openRedInvoiceReq.getInvoiceNo()));
        if (CollectionUtil.isNotEmpty(jsInvoiceOpenTasks)){
            JsInvoiceOpenTask jsInvoiceOpenTask = jsInvoiceOpenTasks.get(0);
            if (openRedInvoiceReq.getSourceSystem().equals(jsInvoiceOpenTask.getSourceSystem())){
                if ("10".equals(jsInvoiceOpenTask.getInvoiceStatus()+"")){
                    if ("2".equals(jsInvoiceOpenTask.getInvoiceSystem())) {
                        LeqiInvoiceRedReq leqiInvoiceRedReq = new LeqiInvoiceRedReq();
                        leqiInvoiceRedReq.setLzfphm(openRedInvoiceReq.getInvoiceNo());
                        leqiInvoiceRedReq.setChyyDm("01");
                        LeqiInvoiceRedRes leqiInvoiceRedRes = leqiApiUtil.sendInvoiceRed(leqiInvoiceRedReq);
                        if (leqiInvoiceRedRes.getCode() != 0000) {
                            result = leqiInvoiceRedRes.getMsg();
                        }
                    }else {
                        {
                            InvoiceRedApplyReq invoiceRedApplyReq = new InvoiceRedApplyReq();
                            //发票类型 1专票,2普票,3电票,4电票纸票
                            String invoice_type = jsInvoiceOpenTask.getInvoiceType()+"";
                            String blueInvoiceNumber =openRedInvoiceReq.getInvoiceNo();
                            String blueInvoiceLine =null;
                            if ("3".equals(invoice_type)){
                                blueInvoiceLine="bs";
                            }else if ("4".equals(invoice_type)){
                                blueInvoiceLine="es";
                                invoiceRedApplyReq.setBlueInvoiceNo(blueInvoiceNumber);
                                invoiceRedApplyReq.setBlueInvoiceCode(jsInvoiceOpenTask.getInvoiceCode());
                                QueryInvoiceReq queryInvoiceReq = new QueryInvoiceReq();
                                queryInvoiceReq.setInvoiceId(Collections.singletonList(jsInvoiceOpenTask.getSettlementNo()));
                                queryInvoiceReq.setSellerTaxnum(jsInvoiceOpenTask.getSellerTaxNo());
                                log.info("调用诺税通发票信息接口入参为：{}", JSONUtil.toJsonStr(queryInvoiceReq));
                                InvoiceRedRes invoiceRedRes = nuoNuoApiUtil.queryInvoice(queryInvoiceReq);
                                log.info("调用诺税通发票信息接口出参为：{}", JSONUtil.toJsonStr(invoiceRedRes));
                                if (invoiceRedRes.getCode()==200){
                                    cn.hutool.json.JSONArray objects = JSONUtil.parseArray(invoiceRedRes.getData());
                                    if (objects.size()>0){
                                        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(objects.get(0));
                                        blueInvoiceNumber=jsonObject.get("allElectronicInvoiceNumber")+"";
                                        List<String> useRedBlueInvoiceNo=new ArrayList<>();
                                        objects.forEach(line1->{
                                            cn.hutool.json.JSONObject jsonObject1 = JSONUtil.parseObj(line1);
                                            String isRedInvoice=jsonObject1.get("isRedInvoice")+"";
                                            if (StringUtils.isNotEmpty(isRedInvoice)&&"1".equals(isRedInvoice)){
                                                useRedBlueInvoiceNo.add(jsonObject.get("allElectronicInvoiceNumber")+"");
                                            }
                                        });
                                        if (!CollectionUtils.isEmpty(useRedBlueInvoiceNo)){
                                            String join = String.join(",", useRedBlueInvoiceNo);
                                            result="发票:"+join+" 已经在诺税红冲，请使用匹配诺税红票";
                                        }
                                    }
                                }
                            }
                            invoiceRedApplyReq.setBlueInvoiceNumber(blueInvoiceNumber);
                            invoiceRedApplyReq.setBlueInvoiceLine(blueInvoiceLine);
                            invoiceRedApplyReq.setTaxNum(jsInvoiceOpenTask.getSellerTaxNo());
                            invoiceRedApplyReq.setOrderNo(openRedInvoiceReq.getExternalDocumentNo());
                            invoiceRedApplyReq.setExtensionNum(openRedInvoiceReq.getExtensionNum());
                            log.info("调用诺税通红冲申请接口入参为：{}", JSONUtil.toJsonStr(invoiceRedApplyReq));
                            InvoiceRedRes invoiceRedRes = nuoNuoApiUtil.sendInvoiceRedApply(invoiceRedApplyReq);
                            log.info("调用诺税通红冲申请接口出参为：{}", JSONUtil.toJsonStr(invoiceRedRes));
                            if (invoiceRedRes.getCode() == 200) {
                                try {
                                    Thread.sleep(800);
                                } catch (InterruptedException e) {

                                }
                                String billId=invoiceRedRes.getData()+"";
                                InvoiceRedSingleReq invoiceRedSingleReq = new InvoiceRedSingleReq();
                                String seller_tax_no = jsInvoiceOpenTask.getSellerTaxNo();
                                invoiceRedSingleReq.setBillId(billId);
                                invoiceRedSingleReq.setTaxNum(seller_tax_no);
                                InvoiceRedRes invoiceRedRes2 = nuoNuoApiUtil.queryRedInvoiceInfo(invoiceRedSingleReq);
                                if (invoiceRedRes2.getCode()==200){
                                    cn.hutool.json.JSONArray objects = JSONUtil.parseArray(invoiceRedRes2.getData());
                                    if (objects.size()>0){
                                        cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(objects.get(0));
                                        String billStatus=jsonObject.get("billStatus")+"";
                                        String openStatus=jsonObject.get("openStatus")+"";
                                        if ("01".equals(billStatus)&&"0".equals(openStatus)){
                                            InvoiceRedReq invoiceRedReq = new InvoiceRedReq();
                                            invoiceRedReq.setSellerTaxnum(seller_tax_no);
                                            invoiceRedReq.setBillId(billId);
                                            invoiceRedReq.setFastRedType(1);
                                            invoiceRedReq.setInvoiceLine(blueInvoiceLine);
                                            log.info("调用诺税通红冲快捷接口入参为：{}", JSONUtil.toJsonStr(invoiceRedReq));
                                            InvoiceRedRes invoiceRedRes1 = nuoNuoApiUtil.sendInvoiceRed(invoiceRedReq);
                                            log.info("调用诺税通红冲快捷接口出参为：{}", JSONUtil.toJsonStr(invoiceRedRes1));
                                            if (invoiceRedRes1.getCode() != 200) {
                                                result=invoiceRedRes.getMessage();
                                            }
                                        }
                                    }
                                }
                            }else {
                                result=invoiceRedRes.getMessage();
                            }
                        }
                    }
                }else {
                    result="当前发票不是正常状态无法红冲！！！";
                }
            }else {
                result="当前发票不归属于当前系没有权限红冲！！！";
            }
        }else {
            result="无效的发票号码！！！";
        }
        if (StringUtils.isBlank(result)) {
            JsInvoiceOpenTask line1 = jsInvoiceOpenTasks.get(0);
            //修改任务表中的状态为待处理中
            line1.setInvoiceStatus(40L);
            jsInvoiceOpenTaskMapper.updateById(line1);
            //新增中间发票任务表中的数据
            JsInvoiceOpenTask jsInvoiceOpenTask = new JsInvoiceOpenTask();
            BeanUtils.copyProperties(line1, jsInvoiceOpenTask);
            jsInvoiceOpenTask.setId(null);
            jsInvoiceOpenTask.setInvoiceNo(null);
            jsInvoiceOpenTask.setInvoiceCode(null);
            jsInvoiceOpenTask.setParentInvoiceNo(line1.getInvoiceNo());
            jsInvoiceOpenTask.setStatus(0L);
            jsInvoiceOpenTask.setUpdateTime(null);
            jsInvoiceOpenTask.setSettlementNo(null);
            jsInvoiceOpenTask.setBillingType(1L);
            jsInvoiceOpenTask.setInvoiceStatus(50L);
            jsInvoiceOpenTask.setBillingType(0L);
            jsInvoiceOpenTask.setAmount(getNegate(jsInvoiceOpenTask.getAmount()));
            jsInvoiceOpenTask.setAmountWithTax("-" + jsInvoiceOpenTask.getAmountWithTax());
            jsInvoiceOpenTask.setTaxAmount("-" + jsInvoiceOpenTask.getTaxAmount());
            jsInvoiceOpenTask.setExternalDocumentNo(IdUtil.simpleUUID());
            jsInvoiceOpenTaskMapper.insert(jsInvoiceOpenTask);
            List<JsInvoiceOpen> jsInvoiceOpens = jsInvoiceOpenMapper.selectList(new LambdaQueryWrapper<JsInvoiceOpen>().eq(JsInvoiceOpen::getInvoiceNo, openRedInvoiceReq.getInvoiceNo()));
            jsInvoiceOpens.forEach(line2 -> {
                //修改正式表中的状态为待处理中
                line2.setInvoiceStatus(40L);
                jsInvoiceOpenMapper.updateById(line2);
            });
        }
        return result;
    }

    @Override
    public JsInvoiceOpenTaskVo invoiceGet(InvoiceGetReq invoiceGetReq) {
        LambdaQueryWrapper<JsInvoiceOpenTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(JsInvoiceOpenTask::getInvoiceNo,invoiceGetReq.getInvoiceNo())
                .eq(JsInvoiceOpenTask::getSourceSystem,invoiceGetReq.getSourceSystem());
        JsInvoiceOpenTask jsInvoiceOpenTask = jsInvoiceOpenTaskDao.getOne(queryWrapper);
        JsInvoiceOpenTaskVo jsInvoiceOpenTaskVo = new JsInvoiceOpenTaskVo();
        BeanUtils.copyProperties(jsInvoiceOpenTask,jsInvoiceOpenTaskVo);
        List<JsInvoiceOpenDetail> jsInvoiceOpenDetails = jsInvoiceOpenDetailMapper.selectList(new LambdaQueryWrapper<JsInvoiceOpenDetail>().eq(JsInvoiceOpenDetail::getExternalDocumentNo, jsInvoiceOpenTask.getExternalDocumentNo()));
        List<JsInvoiceOpenDetailVo> jsInvoiceOpenDetailVos = new ArrayList<>();
        jsInvoiceOpenDetails.forEach(line->{
            JsInvoiceOpenDetailVo jsInvoiceOpenDetailVo = new JsInvoiceOpenDetailVo();
            BeanUtils.copyProperties(line,jsInvoiceOpenDetailVo);
            jsInvoiceOpenDetailVos.add(jsInvoiceOpenDetailVo);
        });
        jsInvoiceOpenTaskVo.setDetails(jsInvoiceOpenDetailVos);
        return jsInvoiceOpenTaskVo;
    }

    @Override
    public List<JsInvoiceOpenTaskVo> invoiceList(InvoiceListReq invoiceListReq) {
        InvoicePageReq invoicePageReq = new InvoicePageReq();
        BeanUtils.copyProperties(invoiceListReq,invoicePageReq);
        invoicePageReq.setPage(1);
        invoicePageReq.setPageSize(500);
        IPage<JsInvoiceOpenTaskVo> jsInvoiceOpenTaskVoIPage = this.invoicePageVo(invoicePageReq);
        return jsInvoiceOpenTaskVoIPage.getRecords();
    }

    @Override
    public List<InvoiceConfVo> confList(InvoiceConfReq invoiceConfReq) {
        List<JsInvoiceConf> jsInvoiceConfList = jsInvoiceConfMapper.selectList(new LambdaQueryWrapper<JsInvoiceConf>()
                .eq(JsInvoiceConf::getConfType, invoiceConfReq.getType()).eq(BaseEntity::getIsDel, "0"));
        List<InvoiceConfVo> invoiceConfVos = new ArrayList<>();
        jsInvoiceConfList.forEach(line->{
            InvoiceConfVo invoiceConfVo = new InvoiceConfVo();
            BeanUtils.copyProperties(line,invoiceConfVo);
            invoiceConfVos.add(invoiceConfVo);
        });
        return invoiceConfVos;
    }

    private BigDecimal getNegate(BigDecimal bigDecimal){
        if (ObjectUtils.isNotEmpty(bigDecimal)){
            return bigDecimal.negate();
        }
        return null;
    }
    private void addInvoiceOpen(JsInvoiceOpen jsInvoiceOpen){
        Map<String, Object> inMap = new HashMap<>();
        inMap.put("INVOICE_NO", jsInvoiceOpen.getInvoiceNo());
        jsInvoiceOpenMapper.deleteByMap(inMap);
        jsInvoiceOpenMapper.insert(jsInvoiceOpen);
    }
    /**
     * 添加开票明细
     *
     * @param jsInvoiceOpenDetail
     */
    public void addInvoiceOpenDetail(JsInvoiceOpenDetail jsInvoiceOpenDetail) {
        jsInvoiceOpenDetailMapper.insert(jsInvoiceOpenDetail);
    }

    /**
     * 更新发票信息
     * @param jsInvoiceOpen
     */
    public void updateInvoiceOpen(JsInvoiceOpen jsInvoiceOpen){
        log.info("更新发票信息{}"+jsInvoiceOpen.getExternalDocumentNo());
        JsInvoiceOpen jsInvoiceOpen1 = jsInvoiceOpenMapper.selectOne(new LambdaQueryWrapper<JsInvoiceOpen>().eq(JsInvoiceOpen::getInvoiceNo, jsInvoiceOpen.getInvoiceNo()));
        if (ObjectUtils.isNotEmpty(jsInvoiceOpen1)) {
            if (ObjectUtils.isNotEmpty(jsInvoiceOpen1.getXmlUrl()) && ObjectUtils.isEmpty(jsInvoiceOpen.getXmlUrl())) {
                jsInvoiceOpen.setXmlUrl(jsInvoiceOpen1.getXmlUrl());
            }
            if (ObjectUtils.isNotEmpty(jsInvoiceOpen1.getOfdUrl()) && ObjectUtils.isEmpty(jsInvoiceOpen.getOfdUrl())) {
                jsInvoiceOpen.setOfdUrl(jsInvoiceOpen1.getOfdUrl());
            }
        }
        //插入发票
        Map<String, Object> inMap = new HashMap<>();
        inMap.put("INVOICE_NO", jsInvoiceOpen.getInvoiceNo());
        jsInvoiceOpenMapper.deleteByMap(inMap);
        jsInvoiceOpenMapper.insert(jsInvoiceOpen);

    }
}
